fn main() {
    let x  = "aaaa";
    let x = x.len();  // 重新绑定值到变量x, 类型可不同

    let s1 = String::from("aaa");
    let s2 = s1;  // 值的所有权发生转移, 变量s1无效
    //println!("{}, {}", s1, s2);

    take_ownership(s2); // 转移了s2的所有权
    // println!("{}", s2); // error

    // 不可变引用, 可Copy
    let s3 = "hi";
    let s2 = s3;

    // 重新绑定变量s2
    let s2 = String::new();
    // 将s2的引用传递给函数, 不转移所有权
    borrowing_immut(&s2);
    println!("{}", s2);

    // -------------
    // 可变引用

    let mut s4 = String::from("mut");
    change_mut(&mut s4);
    println!("{}", s4);

    // 变量同一时刻只能有一个可变引用
    /* let mut r1 = &mut s4;
    let mut r2 = &mut s4; */

    // 可变引用和不可变引用不能同时存在
    /* let r1 = &s4;
    let r2 = &mut s4; */

    // Note: 从rust 1.31后
    // 引用作用域的结束位置 从花括号 变为 最后一次使用的位置
    let mut r1 = &mut s4;
    println!("{}", r1);  // 最后一次使用r1的位置, r1作用域结束
    let mut r2 = &mut s4;
    println!("{}", r2)

    
}

fn take_ownership(s: String) {
    _ = s;
}

fn borrowing_immut(s: &String) -> usize {
    // 作用域内并不拥有引用值的所有权
    //s.push_str("ddd");  // 不能修改变量
    s.len()
}

fn change_mut(s: &mut String) {
    // 持有可变引用，可修改变量
    s.push_str(",hihi");
}
